// Interface
interface IPerson {
    firstName: string;
    lastName: string;
    dateOfBirth: Date;
    FullName: string;
    sayHi(): string;
}

interface IEmployee extends IPerson {
    department: string;
}

// Module
module System {

    // Class
    export class Person implements IPerson {
        
        dateOfBirth: Date;
        // Constructor
        constructor (public firstName: string, public lastName: string) { }

        //constructor ( firstName: string, lastName: string, dateOfBirth : Date) {
        //    this.firstName = firstName;
        //    this.lastName = lastName;
        //    this.dateOfBirth = dateOfBirth;
        // }

        // Instance member
        get FullName() { return this.firstName + " " + this.lastName;  }


        sayHi(){
            return "My name is " + this.FullName;
        }

        testMethod(): string;
        testMethod(param :string): string;
        testMethod(person : Person): string;
        testMethod(obj?: any) {
            if (typeof obj === "string") {
                return "Hi, " + this.FullName;
            } else if (obj instanceof Person) {
                var person = <Person> obj;
                return "Hi, " + person.FullName;
            }
            return "";
        }

	
        // Static member
        static empty = new Person("", "");
    }


    class  Employee extends Person{
        constructor(firstName: string, lastName: string, public department:string){
            super(firstName, lastName);
        } 
    }

}

// Local variables
var p: IPerson = new System.Person("Hasmukh", "Patel");
var fullname = p.FullName;
var name = p.FullName;
var name2 = p.FullName;